package com.ks.winterwarmimage.utils;

import java.nio.ByteBuffer;

/**
 * 控制命令数据封装
 */
public class CmdDataPacket {
    ////////////////////////////通讯协议宏定义//////////////////////////////////
    /** 帧头*/
    public static final byte[] PACKET_HEAD={(byte) 0xAA,0x55};
    /** 帧尾*/
    public static final byte[] PACKET_TAIL={0x0D,0x0A};
    /**开机通知（设备发起）*/
    public static final byte  COM_ON=0x01;//	0x00	开机通知
    /**关机通知（双向）*/
    public static final byte  COM_OFF=0x02;//0x00	上位机发起，先应答，后关机；
    /**关机应答（设备应答）*/
    public static final byte  COM_OFF_ACK= (byte) 0xA2;//	设备发起，先发起，后关机，上位机无需应答。
    /**设置设备的高低温度（上位机发起）*/
    public static final byte  COM_TEMP_SET=0x03;//0-100,0-100	需要设置的最低和最高温度
    /**应答设置设备高低温度（设备应答）*/
    public static final byte  COM_TEMP_SET_ACK= (byte) 0xA3;//0x00
    /**读取高低温（上位机）*/
    public static final byte  COM_TEMP_GET=0x04;//0x00	读高低温
    /**应答读取高低温（设备应答）*/
    public static final byte  COM_TEMP_GET_ACK= (byte) 0xA4;//0-100,0-100	2字节。设置的最低和最高温度
    /**上传当前采集到的温度（设备发起）*/
    public static final byte  COM_UPLOAD_TEMP=0x05;//4字节浮点温度	上传当前采集到的温度
    /**恒温控制（上位机发起）*/
    public static final byte  COM_TEMP_CONTROL=0x06;//0x00或0x01	0x00禁用自动继电器，0x01启用自动继电器
    /**应答恒温控制（设备应答）*/
    public static final byte  COM_TEMP_CONTROL_ACK= (byte) 0xA6;//0x00
    /**开关继电器（上位机发起）*/
    public static final byte  COM_SWITCH_RELAY=0x07;//0x00或0x01或0xFF	0x00关闭继电器;0x01打开继电器；0xff自动切换
    /**应答开关继电器（设备应答）*/
    public static final byte  COM_SWITCH_RELAY_ACK= (byte) 0xA7;//0x00或0x01	0x00继电器关闭;0x01继电器打开；
    /**获取继电器状态（上位机发起）*/
    public static final byte  COM_RELAY_STATE_GET=0x08;//0x00	获取继电器状态（一般在非自动给继电器使用）
    /**应答获取继电器状态（设备应答）*/
    public static final byte  COM_RELAY_STATE_GET_ACK= (byte) 0xA8;//0x00或0x01	0x00继电器关闭;0x01继电器打开；
    /**上传继电器状态（设备发起）*/
    public static final byte  COM_UPLOAD_RELAY_STAT=0x09;//0x00或0x01	上传当前继电器状态。0x00继电器关闭;0x01继电器打开；
    /**OTA升级（上位机发起）*/
    public static final byte  COM_OTA_UPGRADE=0x0A;//OTA文件地址	OTA升级
    /**应答OTA升级（设备应答）*/
    public static final byte  COM_OTA_UPGRADE_ACK= (byte) 0xAA;
    /**OTA升级开始、完成、失败、成功、无更新（设备发起）*/
    public static final byte  COM_OTA_UPGRADE_START=0x0B;//状态数据	0x01升级开始；0x02升级完成；0x03,后面跟更新进度值和总大小；0x04升级失败；0x05升级成功;0x06无更新
    /**照画灯亮度设置（上位机发起）*/
    public static final byte  COM_ILLUMINATE_IMAGE_SET=0x0C;//0-100	照画灯亮度设置
    /**应答照画灯亮度设置（设备应答）*/
    public static final byte  COM_ILLUMINATE_IMAGE_SET_ACK= (byte) 0xAC;//0x00	设置应答
    /**照画灯亮度获取（上位机发起）*/
    public static final byte  COM_ILLUMINATE_IMAGE_GET=0x0D;//0x00	获取照画灯亮度
    /**应答照画灯亮度获取（设备应答）*/
    public static final byte  COM_ILLUMINATE_IMAGE_GET_ACK= (byte) 0xAD;//0-100	返回亮度值
    /**同步状态获取（上位机发起）*/
    public static final byte  COM_SYNC_STATE=0x0E;//0x00	上位机要求获取同步状态
    /**应答同步状态获取（设备应答）*/
    public static final byte  COM_SYNC_STATE_ACK= (byte) 0xAE;//0-100,0x00或0x01	应答当前温度，继电器状态，是否温度恐高症继电器及照画灯亮度
    /**查询绑定设备（上位机发起）*/
    public static final byte CMD_QUERY_BIND_DEV=0x0F;
    /**设备应答绑定信息。未绑定设备不做处理（设备应答）*/
    public static final byte CMD_QUERY_BIND_DEV_ACK= (byte) 0xAF;
    /**更新账号（上位机发起）*/
    public static final byte CMD_UPDATE_ACCOUNT_ID=0x10;//		更新账号
    /**应答更新账号（设备应答）*/
    public static final byte CMD_UPDATE_ACCOUNT_ID_ACK= (byte) 0xB0;//		应答更新账号
    /**更新设备名称（上位机发起）*/
    public static final byte CMD_UPDATE_DEV_NAME=0x11;//		更新设备名称
    /**应答更新设备名称（设备应答）*/
    public static final byte CMD_UPDATE_DEV_NAME_ACK= (byte) 0xB1;//		应答更新设备名称
    /**SC配网完成,专用于解决手机连接的路由器与目标配网路由器不一致的情况下无法收到配网ACK数据（设备发起）*/
    public static final byte CMD_SC_SEND_FINISH=0x12;                    //配网完成应答

    /** 数据报的最大长度 */
    public static final int MAX_DATA_LENGTH=246;
    /**成功*/
    public static final int ESP_OK=0;
    /**失败*/
    public static final int ESP_FAIL= -1;
    //////////////////////////////全局字段////////////////////////////
    /** 命令字节*/
    public byte command;
    /** 数据字段指针，最多246字节*/
    public byte[] data;

    /**
     * 实例化数据包(内部会补足帧头帧尾)
     * @param command 命令字
     * @param data 数据字段
     */
    public CmdDataPacket(byte command,  byte[] data){
        this.command = command;
        this.data = data;
    }
    /**
     * 将数据包转换为字节数组
     * @return
     */
    public byte[] toBytes(){
        ByteBuffer buffer = ByteBuffer.allocate(data.length+5);
        buffer.put(PACKET_HEAD);
        buffer.put(command);
        buffer.put(data);
        buffer.put(PACKET_TAIL);
        return buffer.array();
    }
    /**
     * 将指定的数据包转换为字节数组
     * @param dataPacket 需要转换的数据包
     * @return
     */
    public static byte[] toBytes(CmdDataPacket dataPacket) {
        if(dataPacket!=null) {
            return dataPacket.toBytes();
        }
        return null;
    }
    /**
     * 将字节数组转换为数据包
     * @param data 字节数组
     * @return
     */
    public static CmdDataPacket fromBytes(byte[] data){
        CmdDataPacket dataPacket=null;
        if(data!=null){
            //标准数据包最小大小6字节
            if(data.length>5 && data[0]==PACKET_HEAD[0] && data[1]==PACKET_HEAD[1] &&
               data[data.length-2]==PACKET_TAIL[0] && data[data.length-1]==PACKET_TAIL[1]){
                dataPacket=new CmdDataPacket(data[2], BasicsUtil.subByte(data,3));
            }
        }
        return dataPacket;
    }
}
